import { usePeFile } from "../hooks/pe.ts";

/**
 * 提供对字节数组进行读取操作的实现类，支持多种数据类型的读取，如字符串、字节、单词和双字。
 * @author tongxin
 * @date 2024/4/18 0:11
 */
export class ByteArray implements IByteArray {
  private data: ArrayBuffer;
  private offset: number = 0;

  constructor(data: ArrayBuffer, offset?: number) {
    this.data = data;
    if (offset != null) {
      this.offset = offset;
    }
  }

  read(length: number): IByteArray {
    const buffer = this.readBuffer(length);
    return  new ByteArray(buffer);
  }


  readString(): string;
  readString(length: number): string;
  readString(length: number, offset: number): string;
  readString(length?: number, offset?: number): string {
    if (!offset) {
      this.offset = 0 // 如果没有指定起始偏移量，则默认为0
    }
    const charCode = this.readWord()
    let str = String.fromCharCode(charCode)
    if (str == null || str.charAt(0) == '\u0000') {
      const {calculatePadding} = usePeFile()
      this.offset += calculatePadding(this.offset)
      return ''
    }
    str = str + this.readString()
    return str
  }

  readWord(): number {
    const buffer = this.readBuffer(2)
    return new DataView(buffer).getUint16(0, true)
  }

  readDWord(): number {
    const buffer = this.readBuffer(4)
    return new DataView(buffer).getUint32(0, true)
  }

  readBuffer(length: number): ArrayBuffer {
    const buffer = this.data.slice(this.offset, this.offset + length);
    this.offset += length;
    return buffer;
  }

  getOffset(): number {
    return this.offset;
  }

  setOffset(offset: number) {
    this.offset = offset;
  }

  readByte(): number {
    const buffer = this.readBuffer(1)
    return new DataView(buffer).getUint8(0)
  }
}
